/**
 * UmengSender.java 
 * Copyright © 2009-2014, Liu Tao
 * 
 * @author Liu Tao
 * @create 2014年5月22日
 */
package com.pshare.sender;

import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONObject;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.pshare.util.ByteUtils;
import com.pshare.util.HttpUtils;

/**
 * 友盟推送
 */
public class UmengSender extends PushSender {

	private static final Logger logger = Logger.getLogger(UmengSender.class);
	protected static final Integer ONE_TIME_MAX = 50;
	private static final String COMMA = ",";
	
	public UmengSender() {
		
	}

	public UmengSender(String androidAppKey, String androidMasterSecret) {
		this.androidAppKey = androidAppKey;
		this.androidMasterSecret = androidMasterSecret;
	}
	
	/**
	 * deviceTokens: 友盟消息推送服务对设备的唯一标识。Android的device_token是44位字符串, iOS的device-token是64位。
	 */
	@Override
	public void doPush(Integer type, List<String> deviceTokens, String title, String message, String objId, Integer msgType, String sound) {
		// 友盟多个deviceToken一起发送时，如果其中一个没有被识别，所有对象的消息都不会发送
		int i = 0;
		String str = "";
		List<String> androidTokenStrList = new ArrayList<String>();
		for(String deviceToken : deviceTokens) {
			// 如果超过单次最多发送条数，则新建一个字符串
			if(i >= ONE_TIME_MAX) {
				if(str.endsWith(COMMA)) {
					str = str.substring(0, str.length() -1);
				}
				androidTokenStrList.add(str);
				str = "";
				i = 0;
			}
			str += deviceToken + COMMA;
			i++;
		}
		if(str.endsWith(COMMA)) {
			str = str.substring(0, str.length() -1);
		}
		androidTokenStrList.add(str);
		
		for(String deviceToken : androidTokenStrList) {
			doPush(type, deviceToken, title, message, objId, msgType, sound);
		}
	}
		
	public void doPush(Integer type, String deviceToken, String title, String message, String objId, Integer msgType, String sound) {
		try {

			String typeStr = "";
			switch(type) {
				case 1: 
					typeStr = "unicast";    // 单播
					break;
				case 2:
					typeStr = "listcast";
					break;
				case 3: 
					typeStr = "broadcast";  // 广播
					break;
				case 4: 
					typeStr = "groupcast";  // 组播
					break;
				case 5: 	
					typeStr = "filecast";   // 文件播
					break;
				case 6:
					typeStr = "customizedcast";  // 自定义
				default:
					typeStr = "unicast";
			}
			
			Long timestamp = System.currentTimeMillis();
			String validationToken = DigestUtils.md5Hex(androidAppKey.toLowerCase() + androidMasterSecret.toLowerCase() + timestamp);
			
			JSONObject params = new JSONObject();
			params.put("appkey", androidAppKey);
			params.put("timestamp", timestamp);
			params.put("validation_token", validationToken);
			params.put("type", typeStr);
			if(StringUtils.isNotBlank(deviceToken)) {
				params.put("device_tokens", deviceToken);
			}
			JSONObject payload = new JSONObject();
			payload.put("display_type", "message");
//			payload.put("display_type", "notification");
			JSONObject body = new JSONObject();
			body.put("ticker", title);
			body.put("title", title);
			body.put("text", message);
			if (StringUtils.isNotBlank(sound)) {
				body.put("sound", sound);
			}
			body.put("after_open", "go_activity");
			body.put("activity",  msgType + "");
			body.put("custom", msgType + "");
			payload.put("body", body);
			JSONObject extra = new JSONObject();
			if(StringUtils.isNotBlank(objId)) {
				extra.put("obj_id", objId);
			}
			payload.put("extra", extra);
			params.put("payload", payload);
//			params.put("description", msgType + "");

			byte[] result = null;
			try {
				result = HttpUtils.postJSON(androidPushUrl, params);
			} catch (SocketTimeoutException se) {
				logger.error(se.getMessage(), se);
				// 重试一次
				result = HttpUtils.postJSON(androidPushUrl, params);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
			String msgResult = ByteUtils.bytes2UTF8string(result);
			logger.info("--------------------------------------------------------------");
			logger.info(deviceToken + "--" + message + "--" + msgResult);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

}
